package cn.edu.jxau.test;

import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

public class SimpleHashMap<K,V> extends AbstractMap<K,V> {
    
    public static void main(String[] args) {
        
        Map<Integer,String> map = new SimpleHashMap<>();
        map.put(1,"A");
        map.put(2,"B");
        map.put(3,"C");
        map.put(4,"D");
        map.put(4,"E");
        System.out.println(map.get(1));
        System.out.println(map.get(2));
        System.out.println(map.get(3));
        System.out.println(map.get(4));
        for(Entry entry : map.entrySet()) {
            System.out.println(entry.getKey()+" "+entry.getValue());
        }
    }
    
    private static final int SIZE = 997;
    private List<Entry<K,V>>[] buckets;
    
    private SimpleHashMap() {
       buckets = new List[SIZE];
    }
    
    @Override
    public V get(Object key) {
        
        Objects.requireNonNull(key, "参数key不能为null");
        int bucketIdx = Math.abs(key.hashCode()) % SIZE;
        List<Entry<K,V>> bucket = buckets[bucketIdx];
        if(bucket == null) { //空桶，键值对不存在返回null
            return null;
        }
        for(Entry<K,V> entry : bucket) {
            if(entry.getKey().equals(key)) { //找到键值对，返回键值对的value
                return entry.getValue();
            }
        }
        return null;
    }
    
    @Override
    public V put(K key, V value) {
        
        Objects.requireNonNull(key, "参数key不能为null");
        V oldValue = get(key); //获取旧值，可能为null
        
        // 获取桶 //
        int bucketIdx = Math.abs(key.hashCode()) % SIZE;
        if(buckets[bucketIdx] == null) {
            buckets[bucketIdx] = new ArrayList<Entry<K,V>>();
        }
        List<Entry<K,V>> bucket = buckets[bucketIdx];
        
        // 根据键值对的存在情况更新键值对映射集 //
        for(Entry<K,V> entry : bucket) {
            if(entry.getKey().equals(key)) { //键值对存在，更新键值对的value值
                entry.setValue(value);
                return oldValue;
            }
        }
        bucket.add(new SimpleEntry<K,V>(key,value)); //键值对不存在，添加键值对
        return oldValue;
    }
    
    @Override
    public Set<Map.Entry<K, V>> entrySet() {
        
        Set<Entry<K,V>> entrySet = new HashSet<>();
        for(List<Entry<K,V>> bucket : buckets) {
            if(bucket == null) { //跳过空桶
                continue; 
            }
            for(Entry<K,V> entry : bucket) {
                entrySet.add(entry);
            }
        }
        return entrySet;
    }
}
